package com.hzz.web.app.patrol;

import com.hzz.api.patrol.IPatrolTaskService;
import com.hzz.dto.patrol.PatrolTaskDto;
import com.hzz.framework.PageUtil;
import com.hzz.framework.Response;
import com.hzz.framework.SysErrorCode;
import com.hzz.framework.annotation.ALogOperation;
import com.hzz.framework.annotation.RfUser2Bean;
import com.hzz.framework.exception.ServiceException;
import com.hzz.framework.util.CommonConstant;
import com.hzz.framework.web.controller.BaseController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

@Api(description = "巡查任务")
@RestController("PatrolTaskController")
@Slf4j
public class PatrolTaskController extends BaseController {
    static final String acPrefix = "/api/patrol/patrolTask/";
    
    @Autowired
    IPatrolTaskService patrolTaskService;
    
    @ApiOperation(value = "巡查情况-查询巡查次数")
    @ApiImplicitParams({@ApiImplicitParam(name = "riverCourseCode", value = "河道id", paramType = "query", required = true),
            @ApiImplicitParam(name = "executorAccount", value = "巡查人账号（当前用户账号）", paramType = "query", required = true),
            @ApiImplicitParam(name = "startTime", value = "开始时间", paramType = "query", required = true),
            @ApiImplicitParam(name = "endTime", value = "结束时间", paramType = "query", required = true) })
    @RequestMapping(method = RequestMethod.POST, value = acPrefix + "patrolTimes")
    public Response<Integer> patrolTimes(@RequestBody PatrolTaskDto dto) {
        log.info("APP:PatrolTaskController.patrolTimes........");
        Response<Integer> result = new Response<>();
        try {
            result.setData(patrolTaskService.getPatrolTimes(dto));
        } catch (Exception e) {
            result = Response.error(e.getMessage());
        }
        return result;
    }
    
    // 巡河记录接口-按月
    @ApiOperation(value = "巡河记录-查询巡河记录")
    @ApiImplicitParams({@ApiImplicitParam(name = "areaIds", value = "用户行政区划ids", paramType = "query", required = true),
            @ApiImplicitParam(name = "startTime", value = "开始时间", paramType = "query", required = true),
            @ApiImplicitParam(name = "endTime", value = "结束时间", paramType = "query", required = true) })
    @RequestMapping(method = RequestMethod.POST, value = acPrefix + "patrolTask")
    public Response patrolTask(@RequestBody PatrolTaskDto dto) {
        log.info("APP:PatrolTaskController.patrolTask........{}", dto);
        Response<List> result = new Response<>();
        try {
            // app查询需要关联到用户河道，如果用户没分配河道，让查不出
            if (StringUtils.isBlank(dto.getRiverCourseCode())) {
                dto.setRiverCourseCode("-999999999999999");
            }
            result.setData(patrolTaskService.findListByParam(dto));
        } catch (Exception e) {
            result = Response.error(e.getMessage());
        }
        return result;
    }
    
    // 巡河记录接口-分页查询巡河记录
    @ApiOperation(value = "巡河记录-分页查询巡河记录")
    @ApiImplicitParams({@ApiImplicitParam(name = "areaIds", value = "用户行政区划ids", paramType = "query", required = true),
            @ApiImplicitParam(name = "pageNum", value = "第几页", paramType = "query", required = true),
            @ApiImplicitParam(name = "pageSize", value = "每页条数", paramType = "query", required = true),
            @ApiImplicitParam(name = "startTime", value = "开始时间", paramType = "query", required = true),
            @ApiImplicitParam(name = "endTime", value = "结束时间", paramType = "query", required = true) })
    @RequestMapping(method = RequestMethod.POST, value = acPrefix + "patrolTaskPage")
    public Response patrolTaskPage(@RequestBody PatrolTaskDto dto) {
        log.info("APP:PatrolTaskController.patrolTaskPage........{}", dto);
        Response result = new Response<>();
        try {
            dto.setPageSize(dto.getPageSize());
            dto.setPageNum(dto.getPageNum());
            // app查询需要关联到用户河道，如果用户没分配河道，让查不出
            if (StringUtils.isBlank(dto.getRiverCourseCode())) {
                dto.setRiverCourseCode("-999999999999999");
            }
            
            // UserDto userDto = JwtUtil.getSubject(UserDto.class);
            // dto.setCreateId(userDto.getId());// 用于控制临时任务只能查自己添加的
            // // 非河长和巡查员，不让返回数据
            // if ((userDto.getType() == null || userDto.getType().intValue() != 1) &&
            // !"巡查员".equals(userDto.getJob())) {
            // dto.setExecutorRole("其他角色");
            // }
            
            // 取消巡河中的限制条件 （取消只能查看当前用户行政区划下的任务的限制条件）
            dto.setAreaIds(null);
            
            dto.setDelFlag(0);
            result.setData(patrolTaskService.findListByParamPage(dto));
        } catch (Exception e) {
            result = Response.error(e.getMessage());
        }
        return result;
    }
    
    // 巡河日志列表
    @ApiOperation(value = "巡河日志-本级河长日志")
    @ApiImplicitParams({@ApiImplicitParam(name = "pageNum", value = "第几页", paramType = "query", required = true),
            @ApiImplicitParam(name = "areaIds", value = "当前用户行政区划ids", paramType = "query", required = true),
            @ApiImplicitParam(name = "executorAccount", value = "当前用户账号,填了就是查询我的日志，不填就是根据行政区划查询本级日志", paramType = "query", required = false),
            @ApiImplicitParam(name = "startTime", value = "开始时间", paramType = "query", required = false),
            @ApiImplicitParam(name = "endTime", value = "结束时间", paramType = "query", required = false) })
    @RequestMapping(method = RequestMethod.POST, value = acPrefix + "patrolTaskLog")
    public Response patrolTaskLog(@RequestBody PatrolTaskDto dto) {
        log.info("APP:PatrolTaskController.patrolTaskLog.........{}", dto);
        Response result = new Response();
        try {
            dto.setPageSize(dto.getPageSize());
            dto.setPageNum(dto.getPageNum());
            dto.setDelFlag(0);
            dto.setAreaIds(null);
            result.data = PageUtil.copy(patrolTaskService.findPatrolTaskLog(dto));
        } catch (Exception e) {
            result = Response.error(e.getMessage());
        }
        return result;
    }
    
    @ApiOperation(value = "巡河日志-下级河长日志")
    @ApiImplicitParams({@ApiImplicitParam(name = "pageNum", value = "第几页", paramType = "query", required = true),
            @ApiImplicitParam(name = "pageSize", value = "每页条数", paramType = "query", required = true),
            @ApiImplicitParam(name = "areaIds", value = "当前用户行政区划ids", paramType = "query", required = true),
            @ApiImplicitParam(name = "startTime", value = "开始时间", paramType = "query", required = false),
            @ApiImplicitParam(name = "endTime", value = "结束时间", paramType = "query", required = false) })
    @RequestMapping(method = RequestMethod.POST, value = acPrefix + "patrolTaskLogJunior")
    public Response patrolTaskLogJunior(@RequestBody PatrolTaskDto dto) {
        log.info("APP:PatrolTaskController.patrolTaskLogJunior.........{}", dto);
        Response result = new Response();
        try {
            dto.setPageSize(dto.getPageSize());
            dto.setPageNum(dto.getPageNum());
            dto.setDelFlag(0);
            result.data = PageUtil.copy(patrolTaskService.findPatrolTaskLogJunior(dto));
        } catch (Exception e) {
            result = Response.error(e.getMessage());
        }
        return result;
    }
    
    // 巡河日志详情
    @ApiOperation(value = "巡河日志-详情")
    @ApiImplicitParams({@ApiImplicitParam(name = "id", value = "日志id", paramType = "query", required = true) })
    @RequestMapping(method = RequestMethod.POST, value = acPrefix + "patrolTaskLog/detail")
    public Response findPatrolTaskLogDetailById(@RequestBody PatrolTaskDto dto) {
        log.info("APP:PatrolTaskController.findPatrolTaskLogDetailById.........{}", dto);
        Response result = new Response();
        try {
            dto.setPageSize(CommonConstant.PAGEROW_DEFAULT_COUNT);
            dto.setPageNum(1);
            dto.setDelFlag(0);
            if (ObjectUtils.isEmpty(dto.getId())) {
                result = Response.error("任务id不能为空");
            } else {
                result.data = patrolTaskService.findPatrolTaskLog(dto).getList().get(0);
            }
        } catch (Exception e) {
            result = Response.error(e.getMessage());
        }
        return result;
    }
    
    // 开始巡河接口-保存执行人
    @ApiOperation(value = "巡查任务-开始巡查")
    @ApiImplicitParams({@ApiImplicitParam(name = "id", value = "任务id", paramType = "query", required = true),
            @ApiImplicitParam(name = "executorAccount", value = "执行人账号（当前用户）", paramType = "query", required = true),
            @ApiImplicitParam(name = "executorName", value = "执行人名称", paramType = "query", required = true) })
    @RequestMapping(method = {RequestMethod.POST }, value = acPrefix + "start")
    @RfUser2Bean
    @ALogOperation(type = "修改", desc = "开始巡查")
    public Response start(@RequestBody PatrolTaskDto dto, BindingResult bindingResult) {
        log.info("start.........");
        Response result = new Response(0, "success");
        try {
            if (bindingResult.hasErrors()) {
                String errorMsg = "";
                List<ObjectError> errorList = bindingResult.getAllErrors();
                for (ObjectError error : errorList) {
                    errorMsg += (error.getDefaultMessage()) + ";";
                }
                result = Response.error(errorMsg);
            } else {
                synchronized (this.getClass()) {
                    PatrolTaskDto data = new PatrolTaskDto();
                    data.setId(dto.getId());
                    data = patrolTaskService.findDataById(data);
                    // 判断任务开始时间，没到开始时间不能执行
                    if (new Date().before(data.getStartTime())) {
                        result.setCode(9999);
                        result.setMessage("该任务未开始，不能执行");
                        return result;
                    }
                    // 判断任务结束时间，过期的任务不能执行
                    if (new Date().after(data.getEndTime())) {
                        result.setCode(9999);
                        result.setMessage("该任务已经过期，不能执行");
                        return result;
                    }
                    // UserDto userDto = JwtUtil.getSubject(UserDto.class);
                    // if (data.getExecutorAccount().equals(userDto.getAccount())) {
                    // throw new ServiceException(SysErrorCode.defaultError, "当前登录用户和参数[巡河人账号]不一致");
                    // }
                    if (StringUtils.isNotBlank(data.getExecutorAccount()) && !data.getExecutorAccount().equals(dto.getExecutorAccount())) {
                        throw new ServiceException(SysErrorCode.defaultError, "此任务已经有其他河长执行");
                    }
                    data.setExcStartTime(new Date());
                    data.setExecutorAccount(dto.getExecutorAccount());
                    data.setExecutorName(dto.getExecutorName());
                    data.setTaskStatus(CommonConstant.TASK_STATUS_巡查任务_巡查中);
                    result = patrolTaskService.saveOrUpdateData(data);
                }
            }
        } catch (Exception e) {
            log.error("start exception:{}", e);
            result = Response.error(e.getMessage());
        }
        return result;
    }
    
    // 巡河结束-验证执行人-保存巡河数据-轨迹-巡河公里数
    @ApiOperation(value = "巡查任务-结束巡查")
    @ApiImplicitParams({@ApiImplicitParam(name = "id", value = "任务id", paramType = "query", required = true),
            @ApiImplicitParam(name = "executorAccount", value = "执行人账号（当前用户）", paramType = "query", required = true),
            @ApiImplicitParam(name = "patrolTrack", value = "轨迹坐标点,json串的key必须使用双引号存储，格式：[{\"lng\":116.297611,\"lat\":40.047363}...]", paramType = "query", required = true),
            @ApiImplicitParam(name = "patrolKilometer", value = "巡查公里数", paramType = "query", required = true) })
    @RequestMapping(method = {RequestMethod.POST }, value = acPrefix + "end")
    @RfUser2Bean
    @ALogOperation(type = "修改", desc = "结束巡查")
    public Response end(@RequestBody PatrolTaskDto dto, BindingResult bindingResult) {
        log.info("end.........");
        Response result = new Response(0, "success");
        try {
            if (bindingResult.hasErrors()) {
                String errorMsg = "";
                List<ObjectError> errorList = bindingResult.getAllErrors();
                for (ObjectError error : errorList) {
                    errorMsg += (error.getDefaultMessage()) + ";";
                }
                result = Response.error(errorMsg);
            } else {
                PatrolTaskDto data = new PatrolTaskDto();
                data.setId(dto.getId());
                data = patrolTaskService.findDataById(data);
                if (StringUtils.isNotBlank(data.getExecutorAccount()) && !data.getExecutorAccount().equals(dto.getExecutorAccount())) {
                    throw new ServiceException(SysErrorCode.defaultError, "此任务已经有其他河长执行");
                }
                data.setExcEndTime(new Date());
                data.setPatrolKilometer(dto.getPatrolKilometer());
                data.setPatrolTrack(dto.getPatrolTrack());
                data.setTaskStatus(CommonConstant.TASK_STATUS_巡查任务_已巡查);
                result = patrolTaskService.saveOrUpdateData(data);
                // request.getSession().setAttribute(acPrefix + "save." + dto.getToken(), "1");
            }
        } catch (Exception e) {
            log.error("end exception:{}", e);
            result = Response.error(e.getMessage());
        }
        return result;
    }
    
    // 添加巡查任务
    @ApiOperation(value = "巡查任务-新增巡查任务")
    @ApiImplicitParams({@ApiImplicitParam(name = "riverCourseCode", value = "河道id", paramType = "query", required = true),
            @ApiImplicitParam(name = "taskType", value = "任务类型（直接填写临时任务或紧急任务）", paramType = "query", required = true),
            @ApiImplicitParam(name = "executorRole", value = "执行人角色，河长或巡查员，取当前用户角色", paramType = "query", required = true),
            @ApiImplicitParam(name = "startTime", value = "任务开始时间", paramType = "query", required = true),
            @ApiImplicitParam(name = "endTime", value = "任务结束时间", paramType = "query", required = true),
            @ApiImplicitParam(name = "taskContent", value = "任务内容", paramType = "query", required = true),
            @ApiImplicitParam(name = "creatorLevel", value = "河长级别（省、市、区、街、村）（取选择的河道的河流等级）", paramType = "query", required = true) })
    // @RequiresPermissions(value = {"patrolTask:add", "patrolTask:edit" }, logical = Logical.OR)
    @RequestMapping(method = {RequestMethod.POST }, value = acPrefix + "save")
    @RfUser2Bean
    @ALogOperation(type = "修改", desc = "临时巡查任务")
    public Response save(@RequestBody PatrolTaskDto dto, BindingResult bindingResult) {
        log.info("save.........");
        Response result = new Response(0, "success");
        try {
            // if ("1".equals(request.getSession().getAttribute(acPrefix + "save." + dto.getToken()))) {
            // throw new RuntimeException("请不要重复提交!");
            // }
            if (bindingResult.hasErrors()) {
                String errorMsg = "";
                List<ObjectError> errorList = bindingResult.getAllErrors();
                for (ObjectError error : errorList) {
                    errorMsg += (error.getDefaultMessage()) + ";";
                }
                result = Response.error(errorMsg);
            } else {
                SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
                // 判断任务开始时间是不是在今天之前，不能创建今天之前的任务
                if (sdf1.parse(sdf1.format(new Date())).after(sdf1.parse(sdf1.format(dto.getStartTime())))) {
                    result.setCode(9999);
                    result.setMessage("不能创建今日之前的任务");
                    return result;
                }
                result = patrolTaskService.saveOrUpdateData(dto);
                // request.getSession().setAttribute(acPrefix + "save." + dto.getToken(), "1");
            }
        } catch (Exception e) {
            result = Response.error(e.getMessage());
        }
        return result;
    }
}
